
// This guard ensures that windows implementation is used only
// on windows platform.
#ifndef MY_USE_WIN32

    #error Windows version of __FILE__ is used without MY_USE_WIN32 defined.

#endif

#include <windows.h>

#include "Concurrent/Win32/MutexImp.hpp"
#include "Debug/Assert.hpp"

namespace My
{
    MutexImp::MutexImp(bool is_recursive)

        #ifdef MY_USE_DEBUG

            : m_Recursive(is_recursive),
              m_Locks(0)

        #endif

    {
        InitializeCriticalSection(&m_CriticalSection);
    }

    MutexImp::~MutexImp()
    {
        MY_ASSERT(m_Locks == 0, "Mutex::~Mutex() called on locked Mutex.");

        DeleteCriticalSection(&m_CriticalSection);
    }

    void MutexImp::Lock()
    {
        MY_ASSERT(m_Recursive || m_Locks == 0, "Mutex::Lock() called on locked and non-recursive mutex.");

        EnterCriticalSection(&m_CriticalSection);

        #ifdef MY_USE_DEBUG

            if(m_Recursive)
                ++m_Locks;
            else
                m_Locks = 1;

        #endif
    }

    bool MutexImp::TryLock()
    {
        bool success = TryEnterCriticalSection(&m_CriticalSection);

        #ifdef MY_USE_DEBUG

            if(success && (m_Recursive || m_Locks == 0))
                ++m_Locks;

        #endif

        return success;
    }

    void MutexImp::Unlock()
    {
        #ifdef MY_USE_DEBUG

            --m_Locks;

        #endif

        LeaveCriticalSection(&m_CriticalSection);
    }
}
